package com.bidevalution.business.handler;

import com.bidevalution.business.common.AnalysisFileMd5Util;
import com.bidevalution.business.common.AnalysisFileUtils;
import com.bidevalution.business.common.AnalysisZip4jUtil;
import com.qtp.core.util.Base64Util;
import com.qtp.core.util.GsonUtil;
import net.lingala.zip4j.exception.ZipException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Base64;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 将投标文件里的pdf解压出来，放到指定目录下
 * @author huyiqi
 */
public class TbXfHandler extends BaseHandler {
    private static final String PROJECT_NODE ="ConstructProject";
    private static final String FILE_NODE ="BidFile\\d+";
    private static final Logger log = LoggerFactory.getLogger(TbXfHandler.class);


    private FileOutputStream fos;
    private FileChannel osChannel;

    private String dir;
    private String batchDir;
    private String fileHash;
    private String fileName;
    private String filePass;
    private String tender;

    public TbXfHandler(String batchDir) {
        this.batchDir = batchDir;
    }

    @Override
    public void endDocument() throws SAXException {
        try {
            File file = new File(fileName);
            String md5 = AnalysisFileMd5Util.getMD5Three(fileName);
            if (this.fileHash == null || !md5.toLowerCase().equals(this.fileHash.toLowerCase())) {
                throw new SAXException("信封损坏请检查");
            }
            //解压
            System.out.println("=======解压投标文件开始=======");
            AnalysisZip4jUtil.unZip(file, file.getParent(), filePass);
            System.out.println("=======解压投标文件完成=======");
            //将pdf拷贝到指定目录下
            System.out.println("=======拷贝PDF到新的目录开始=======");
            FileUtils.copyDirectory(new File(dir+File.separator+"TBFile"), new File(batchDir+File.separator+tender));
            System.out.println("=======拷贝PDF到新的目录完成=======");
            //删除临时文件
            System.out.println("=======删除临时目录开始=======");
            FileUtils.deleteDirectory(new File(dir));
            System.out.println("=======删除临时目录结束=======");
        } catch (ZipException e) {
            log.error("解压异常",e);
        } catch (IOException e) {
            log.error("拷贝文件异常",e);
        } finally {
            colseIO();
            if (!new File(fileName).delete()){
                log.info("LOG[]endDocument1[]{},params={}", "文件删除失败",fileName);
            }
        }
        super.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        try {
            super.startElement(uri, localName, qName, attributes);
            if (PROJECT_NODE.equals(qName)) {
                this.loadProject(attributes);
            } else if (Pattern.matches(FILE_NODE, qName)) {
                this.appendFile(attributes);
            }
        } catch (SAXException e){
            colseIO();
            throw e;
        }
    }

    private void loadProject(Attributes attributes) throws SAXException {
        // 项目ID
        tender = attributes.getValue("Tender");
        this.fileHash = attributes.getValue("FileHash");
        try {
            setDir();
            this.filePass = new String(Base64Util.decryptBase64(attributes.getValue("UniqueCode")), "GB2312");
            this.fileName = this.dir + File.separator + tender +".zip";
            AnalysisFileUtils.createFile(this.fileName);
            fos = new FileOutputStream(new File(this.fileName));
            osChannel = fos.getChannel();
        } catch (Exception e) {
            log.error("解析文件错误", e);
            throw new SAXException("解析文件错误");
        }
    }

    /**
     * 合并
     */
    private void appendFile(Attributes attributes) throws SAXException {
        String fileValue = attributes.getValue("Value");
        //base64解码
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodeStrs = decoder.decode(fileValue);
        ByteBuffer buff = ByteBuffer.wrap(decodeStrs);
        buff.put(decodeStrs);
        buff.flip();
        try {
            osChannel.write(buff);
        } catch (IOException e) {
            log.error("LOG[]appendFile_124[]{},error={}","异常日志",GsonUtil.toJsonWithGson(e));
            throw new SAXException("解析文件错误");
        } finally {
            buff.clear();
        }

    }

    private void colseIO() {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                log.error("LOG[]colseIO_137[]{},error={}","异常日志",GsonUtil.toJsonWithGson(e));
            }
        }
    }

    private void setDir() {
        this.dir = System.getProperty("user.dir") + File.separator +"exportPdfTemp" + File.separator + UUID.randomUUID().toString();
    }
}
